using Autofac;
using Autofac.Extensions.DependencyInjection;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
using NLog;
using ThresholdAssistant.Attributes;
using ThresholdAssistant.Attributes.Extensions;
using ThresholdAssistant.Autofac;
using ThresholdAssistant.Http;
using ThresholdAssistant.Swagger;
using ThresholdAssistant.WebAPI.Filters;

namespace ThresholdAssistant.WebAPI
{
    /// <summary>
    /// 启动程序
    /// </summary>
    public class Startup
    {
        /// <summary>
        /// 配置
        /// </summary>
        public IConfiguration Configuration { get; }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="configuration"></param>
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        /// <summary>
        /// 依赖注入
        /// </summary>
        /// <param name="builder"></param>
        public void ConfigureContainer(ContainerBuilder builder)
        {
            //使用Autofac注入
            builder.UseAutofac<ControllerModule>();
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="services"></param>
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddAutofac();//添加Autofac依赖注入
            services.AddPollyClientUtil();
            services.AddDistributedMemoryCache();//添加分布式内存缓存
            services.AddKnife4Gen("阈值助手API文档", "1.0.0");//添加Swagger接口文档描述
            services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme).AddCookie();//添加Cookie支持
            services.Configure<ApiBehaviorOptions>(options => { options.SuppressModelStateInvalidFilter = true; });//禁用默认验证行为
            services.AddCors(options =>
            {
                options.AddPolicy("MyPolicy",
                builder =>
                {
                    builder.WithOrigins("*", "http://localhost:6001")
                    .AllowAnyMethod()
                    .AllowAnyHeader()
                    .AllowCredentials();
                });
            });

            services.AddControllers(options =>
            {
                options.Filters.Add<GlobalExceptionAttribute>();//添加全局异常处理类
                //options.Filters.Add<ModelValidAttribute, ErrorResultEnum>();//添加全局模型验证
                options.Filters.Add<ModelValidFilter>();//添加全局模型验证
            })
            .AddNewtonsoftJson(options =>
            {
                options.SerializerSettings.DateFormatString = "yyyy-MM-dd HH:mm:ss";//设置时间格式
                options.SerializerSettings.DateTimeZoneHandling = DateTimeZoneHandling.Utc;
                options.SerializerSettings.ContractResolver = new DefaultContractResolver();//不使用驼峰
                options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;//忽略循环引用
            }).SetCompatibilityVersion(CompatibilityVersion.Version_3_0);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="app"></param>
        /// <param name="env"></param>
        /// <param name="host"></param>
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env, IHost host)
        {
            app.UseDeveloperExceptionPage();
            app.UseKnife4UI();

            app.UseNLogMiddleware(LogLevel.Trace, true);
            //app.UseHttpsRedirection();
            app.UseStaticFiles();
            app.UseDeveloperExceptionPage();
            app.UseRouting();
            app.UseCors("MyPolicy");
            //由于在ASP.NET Core 3.0中，app.UseMvc被app.UseRouting和app.UseEndpoints替代，
            //所以app.UseAuthentication和app.UseAuthorization，要放在app.UseRouting、app.UseCors之后，并且在app.UseEndpoints之前
            app.UseAuthentication();
            app.UseAuthorization();
            host.UseAutofacService();
            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();
            });
        }
    }
}